#pragma once
#include <Windows.h>
#include <memory>
extern "C" 
{
#include <libavcodec\avcodec.h>
}

#include <concurrent_queue.h>
#include <atomic>
#include <thread>
#include <d3d11.h>
#include <wrl/client.h>
#include <deque>
#include <mutex>
#include "OutputInterface.h"

using Microsoft::WRL::ComPtr;

class Encoder
{
public:
	Encoder();
	~Encoder();

	int Start(uint32_t width, uint32_t height, uint32_t frameRate, uint64_t bitRate, OutputInterface* output);
	OutputInterface* Stop();

	void WriteFrame(const BYTE* yuvData, uint64_t pts);

	bool IsRuning();

private:
	void VideoEncoder();
	void Encode(AVCodecContext *context, AVFrame *frame);

	std::thread m_encodecWorker;
	std::atomic_bool m_encodecWoking;
	
	std::deque<AVFrame*> m_frameDeque;
	std::mutex m_frameDequeMutex;
	uint32_t m_frameDequeMaxLen;
	concurrency::concurrent_queue<AVFrame*> m_idleFrames;

	AVPixelFormat m_framePixelFormat;
	HANDLE m_frameQueueSema;
	uint64_t m_bitRate;
	uint32_t m_width, m_height;
	int32_t m_frameRate;
	OutputInterface* m_output;
};

